// Impostazioni variabili di base per Cwn2

/**
* CartoWebNet2 JavaScript Library
*
* @module CWN2
*/

//Namespace: CWN2
CWN2 = {};
 
//Namespace: CWN2.base
CWN2.base = CWN2.base || {};

// flag per debug
CWN2.base.DEBUG = false;

// variable globale per la mappa
CWN2.base.map = null;


//#include <base.js>

/**
* 
* Classe per gestire le funzioni di callback
* 
* @namespace CWN2
* @class event
* 
* 
*/


//Namespace: CWN2.event
CWN2.event = {
	
	/**
	* 
	* Funzione di callback che viene chiamata in seguito ad un evento di select
	* su una feature vettoriale
	* 
	* @method onFeatureSelect
	* 
	* @param {obj} evt Oggetto evento
	* 
	*/

	onFeatureSelect: function(evt) {
	    var feature = evt.feature;
	
	    // se impostato attributo infoUrl sul GeoJSON con i dati uso quello
	    // altrimenti uso la infoUrl definita sulla configurazione del layer
	    var url = feature.attributes.infoUrl;
	    var target = feature.attributes.infoTarget;
		if (!url) {
			var layerName = evt.object.name;
			var layerConfig = CWN2.configuration.getLayerConfigByName(layerName);
			url = layerConfig.infoUrl;
			target = layerConfig.infoTarget;
			// attribute replacement {$attribute_name} - utilizzo la funzione OpenLayers.Style.createLiteral
			url = OpenLayers.Style.createLiteral(url,feature.attributes,feature);
		}
		
		if (url) {
			if (target) {
				window.open(url,target,'');
			}
			else {
				window.document.location.href=url;
			}
		}
	},
	
	/**
	* 
	* Funzione di callback che viene chiamata in seguito ad un evento di unSelect
	* su una feature vettoriale
	* 
	* @method onFeatureUnselect
	* 
	* @param {obj} evt Oggetto evento
	* 
	*/
	
	onFeatureUnselect: function (evt) {
    	feature = evt.feature;
	},
	
	/**
	* 
	* Funzione di callback che viene chiamata in seguito all'evento di Mousemove
	* e determina la scrittura sulla statusbar delle coordinate X e Y
	* 
	* @method onMouseMove
	* 
	* @param {obj} evt Oggetto evento
	* 
	*/
	
	coordinateReadOut: function(e) {
			
		var lonLat = this.getLonLatFromPixel(e.xy);
		
		
		// TODO: gestione conversione coordinate da 900913 a GB / WGS84
		/*		
 		if (this.displayProjection) {
			lonLat.transform(this.getProjectionObject(),
					this.displayProjection);
		} 
		*/

		Ext.getCmp("x-coord").setText("X: " + lonLat.lon.toFixed(0));
		Ext.getCmp("y-coord").setText("Y: " + lonLat.lat.toFixed(0));

	}
	
};






/* funzioni per gestione popup
CWN2.event.onPopupClose = function(evt) {
    // 'this' is the popup.
    selectControl.unselect(this.feature);
}

CWN2.event.onFeatureSelect = function(evt) {
    feature = evt.feature;
    popup = new OpenLayers.Popup.FramedCloud("featurePopup",
                             feature.geometry.getBounds().getCenterLonLat(),
                             new OpenLayers.Size(100,100),
                             "<h2>"+feature.attributes.title + "</h2>" +
                             feature.attributes.description,
                             null, true, onPopupClose);
    feature.popup = popup;
    popup.feature = feature;
    this.addPopup(popup);
}

CWN2.event.onFeatureUnselect = function(evt) {
    feature = evt.feature;
    if (feature.popup) {
        popup.feature = null;
        this.removePopup(feature.popup);
        feature.popup.destroy();
        feature.popup = null;
    }
}
*/

//#include <base.js>

/**
* 
* Classe gestione json - Contiene metodi per caricare json ecc...
* 
* @namespace CWN2
* @class json
* 
*/

CWN2.json = {
	
/**
* 
* Funzione per caricare un oggetto json remoto in maniera sincrona o asincrona
* 
* @method load
* 
* @param {String} url Url del file o del servizio
* @param {bool} sync Flag che indica se effettuare una richiesta sincrona
* @return {obj} Oggetto Javascript 
* 
*/

	load: function(url,sync) {
	  if (CWN2.base.DEBUG) {
		console.log('CWN2.json.load');
	  }

	  var request;
	  // richiesta sincrona
	  if (sync) {
		  if (window.XMLHttpRequest) {              
		    request =new XMLHttpRequest();              
		  } else {                                  
		    request = new ActiveXObject("Microsoft.XMLHTTP");
		  }
		  if (request) {
		     request.open("GET", url, false);                             
		     request.send(null);
			return JSON.parse(request.responseText);
		  } else {
		     return false;
		  }
	  } else {
	  	this.loadAsync(url);
	  }
	},
	/**
	* 
	* Funzione per caricare un oggetto json remoto in maniera asincrona
	* 
	* @method loadAsync
	* 
	* @param {String} url Url del file o del servizio
	* @param {bool} sync Flag che indica se effettuare una richiesta sincrona 
	* @return {obj} Oggetto Javascript 
	* 
	*/
	loadAsync: function(url){
	  //TODO: da rivedere
	  // richiesta asincrona
		function handler(request) {
			return JSON.parse(request.responseText);
		}
		request = OpenLayers.Request.GET({
	    	'url': url,
	    	'callback': handler
		});	
	}
	
	
};

//#include <base.js>
/*
 *  olExtensions
 *  
 *  Estensioni delle classi Openlayers
 *  
 */	


/*
 *  Metodo: loadGeoJSON 
 *  
 *  Estensione della classe OpenLayers.Layer.Vector
 *  
 *  Carica le feature di un GeoJSON in un layer di tipo OpenLayers.Layer.Vector
 *  
 *  Parametri:
 *  geoJSON - oggetto GeoJSON da caricare oppure url di un file contenente l'oggetto
 *  
 *  TODO: gestire la possibilita' di caricare il json da un file esterno di cui viene fornita la url
 *  parametro geoJSON se stringa --> url altrimenti oggetto GeoJSON
 *  
 *  TODO: gestire la strategia di cluster
 *  
 */	
OpenLayers.Layer.Vector.prototype.loadGeoJSON = function (geoJSON) {
	if (CWN2.base.DEBUG) {
		console.log('Openlayers.Layer.Vector.loadGeoJSON');
	}

	//TODO: gestire clustering
	//this.strategies = [new OpenLayers.Strategy.Cluster({distance:42})];

	//Se il protocollo e' impostato e il formato del protocollo non e' GeoJSON ritorno
	if (this.protocol && this.protocol.format.CLASS_NAME !== 'OpenLayers.Format.GeoJSON') {
		if (CWN2.base.DEBUG) {
			console.log('Layer non GeoJSON');
		}
		return;
	}

	// se parametro geoJSON e' una stringa lo interpreto come la url del file contenente il json
	// TODO non testato - sincrono?
	if (typeof geoJSON === 'string') {
		geoJSON = CWN2.json.load(geoJSON,true);
	}
	
	// definisco il formato
	var format_geojson = new OpenLayers.Format.GeoJSON({
	  'internalProjection': new OpenLayers.Projection(this.map.projection),
	  'externalProjection': this.projection
	});

	// deserializzo il json nelle feature	
	var museiFeatureCollection = format_geojson.read(geoJSON);
	 
	// carico le feature sul layer
	this.addFeatures(museiFeatureCollection);	
	
	// faccio lo zoom sugli elementi caricati
	this.map.zoomToExtent(this.getDataExtent(),false);
};

OpenLayers.Layer.Vector.prototype.zoomToSelected = function () {
	if (CWN2.base.DEBUG) {
		console.log('Openlayers.Layer.Vector.zoomToSelected');
	}

	var fts = this.selectedFeatures;
	var max = fts.length;
	var i;
	var bounds = fts[0].geometry.getBounds().clone();
	 
	for(i = 1; i < max; i++) {
			    bounds.extend(fts[i].geometry.getBounds());
	}
	
	this.map.zoomToExtent(bounds,false);
};


//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>

/**
* 
* Configurazione Applicazione
* 
* @namespace CWN2
* @class configuration
* 
*/

CWN2.configuration = (function (){
	
	// dependencies
	
	// private properties
	
	// private methods
	
	// ritorno l'oggetto config - Public API
	return {
		
		/**
		* @property name
	    * @type {string}
		*/
		name: "Configurazione CWN2",
		/**
		* @property mapOptions
	    * @type {mapOptions}
		*/
		mapOptions: {},
		/**
		* @property layout
	    * @type {layoutConfig}
		*/
		layout: {},
		/**
		* @property statusbar
	    * @type {statusConfig}
		*/
		widgets: [],		
		/**
		* @property toolbar
	    * @type {toolbarConfig}
		*/
		toolbar: {},		
		/**
		* @property olControls
	    * @type [{olControls}]
		*/
		olControls: [],
		/**
		* @property layers
	    * @type [{layerConfig}]]
		*/
		layers: [],
		
		/**
		* 
		* Load a json containing the configuration
		* 
		* @method load
		* 
		* @param {String} url Url of the json configuration file
		* 
		* @return: {configuration}
		* 
		*/
		 
		load: function(url) {
		
			if(CWN2.base.DEBUG) {
				console.log('CWN2.configuration.load');
			} 
		
			// carico il Json
			var config = CWN2.json.load(url,true);
			
			// creo gli oggetti Bounds per le opzioni di tipo "Extent"
			var options = config.mapOptions;
			for (var option in options) {
				if ((option === "maxExtent") || (option === "restrictedExtent")) {
					options[option] = OpenLayers.Bounds.fromString(options[option]);
				}
			}

			// imposto le proprieta'
			this.name = config.name || this.name ;
			this.mapOptions = config.mapOptions;
			this.layout = config.layout;
			this.olControls = config.olControls;
			this.widgets = config.widgets;
			this.toolbar = config.toolbar;
			this.layers = config.layers;
			
			return this;
			
		},
		
		
		/**
		* 
		* Return the configuration of a layer with a given name
		* 
		* @method getLayerConfigByName
		* 
		* @param {String} layerName The name of the layer
		* 
		* @return 	{layerConfig}
		* 
		*/
		getLayerConfigByName: function (layerName) {
			var layers = CWN2.configuration.layers;
			var len = CWN2.configuration.layers.length;
			for (var i = 0; i < len; i++) {
				if (layers[i].name===layerName) {
					return layers[i];
				}
			}
		},
		
		/**
		* 
		* Return the configuration of a toolbar item with a given type
		* 
		* @method getToolbarItemConfigByType
		* 
		* @param {String} itemType The type of the item
		* 
		* @return 	{toolbarItemConfig}
		* 
		*/
		getToolbarItemConfigByType: function (itemType) {

			for (var group in CWN2.configuration.toolbar.itemGroups) {
				for (var item in CWN2.configuration.toolbar.itemGroups[group].items) {
					if (CWN2.configuration.toolbar.itemGroups[group].items[item].type === itemType) {
						return CWN2.configuration.toolbar.itemGroups[group].items[item];
					}
				}
			}			
			
		},
		
		/**
		* 
		* Return the configuration of a widget with a given type
		* 
		* @method getWidgetConfigByType
		* 
		* @param {String} widgetType The type of the item
		* 
		* @return 	{widgetConfig}
		* 
		*/
		getWidgetConfigByType: function (widgetType) {

			var widgets = CWN2.configuration.widgets;
			var len = widgets.length;
			for (var i = 0; i < len; i++) {
				if (widgets[i].type===widgetType) {
					return widgets[i];
				}
			}			
			
		}		
	};
}());

//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Factory per creazione di controlli OL
* 
* @namespace CWN2
* @class controlFactory
* 
*/

CWN2.controlFactory = {

	/**
	* 
	* Create an OpenLayers control based on a given configuration
	* 
	* @method createControl
	* 
	* @param {controlConfig} controlConfig Obj containing the control configuration 
	* 
	* @return: 	{OpenLayers.Control}
	* 
	*/ 
	
	createControl: function(controlConfig) {

		if (CWN2.base.DEBUG) {
			console.log('CWN2.controlFactory.createControl');
		}
		try {
			return new OpenLayers.Control[controlConfig.type](controlConfig.options);
		}
		catch (exception) {
			throw('CWN2.controlFactory.createControl: OpenLayers.Control.' + controlConfig.type + ' non implementato');
			return null;			
		}
		
	}
	
};
//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Factory per creazione di layers di tipo OL
* 
* @namespace CWN2
* @class layerFactory
* 
*/

CWN2.layerFactory = {

	/**
	* 
	* Create an OpenLayers layer based on a given configuration
	* 
	* @method createLayer
	* 
	* @param {layerConfig} layerConfig Obj containing the layer configuration 
	* 
	* @return: 	{OpenLayers.Layer}
	* 
	*/ 
	
	createLayer: function(layerConfig) {

		if (CWN2.base.DEBUG) {
			console.log('CWN2.layerFactory.createLayer');
		}
		return CWN2.layerFactory[layerConfig.type](layerConfig);
	
	},
	
	/*
	* 
    * Metodi per creazione dei layer Openlayers dei vari tipi
    *
    */ 
    
    // google stradario
	google_roadmap: function(layerConfig) {
		if (CWN2.base.DEBUG) {
			console.log('google_roadmap');
		}
		var layerType = google.maps.MapTypeId.ROADMAP;
		return CWN2.layerFactory.google(layerType,layerConfig);
	},
	
    // google satellite
	google_satellite: function(layerConfig) {
		if (CWN2.base.DEBUG) {
			console.log('google_satellite');
		}
		var layerType = google.maps.MapTypeId.SATELLITE;
		return CWN2.layerFactory.google(layerType,layerConfig);
	},
	
	// google generico
	google: function(layerType,layerConfig) {
		var	olLayer = new OpenLayers.Layer.Google(
			layerConfig.name,
			{
				type: layerType,
				minZoomLevel: layerConfig.minZoomLevel, 
				maxZoomLevel: layerConfig.maxZoomLevel 
			}
		);
		return olLayer;
	},
	
	// Vettoriale GeoJSON
	GeoJSON: function(layerConfig) {
		if (CWN2.base.DEBUG) {
			console.log('GeoJSON');
		}
		var layerOptions = {};
		layerOptions.projection = layerConfig.projection || 'EPSG:900913';
		if (layerConfig.url !== undefined){
			layerOptions.protocol = new OpenLayers.Protocol.HTTP({
					url: layerConfig.url,
					format: new OpenLayers.Format.GeoJSON({})
				});
			layerOptions.strategies = layerConfig.strategies || [new OpenLayers.Strategy.Fixed()];
	
		}
		var olLayer = new OpenLayers.Layer.Vector(
			layerConfig.name,
			layerOptions
		);
		// gestione stile
		if (layerConfig.styleMap !== undefined){
			olLayer.styleMap = new OpenLayers.StyleMap(layerConfig.styleMap);			
		}
		return olLayer;
	}

};
//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Classe CWN2.MapBuilder - Build the Openlayers.Map
* 
* @namespace CWN2
* @class MapBuilder
* 
*/

CWN2.MapBuilder = {
	
	/**
	* 
	* Build the OL Map
	* 
	* @method build
	* 
	* @param {String} div Name of the div  
	* 
	*/ 
	
	build: function(div) {
		
		if (CWN2.base.DEBUG) {
			console.log('CWN2.MapBuilder.build');
		}

		var config = CWN2.configuration;
		
		// imposto le mapOptions
		var mapOptions = config.mapOptions;
		// azzero i controlli della mappa OL - altrimenti fa vedere il controllo PanZoom sempre
		mapOptions.controls=[];

		// Creo la mappa OL
		CWN2.base.map = new OpenLayers.Map(div,mapOptions)		

		// Inizializzo i controlli per la mappa OL
		this.initControls(config.olControls);

		// Carico i layers alla mappa OL
		this.loadLayers(config.layers);

		// Vado allo zoom iniziale
		if(!CWN2.base.map.getCenter()){
			CWN2.base.map.zoomToMaxExtent();
		}
	},
	
	/**
	* 
	* Add an array of layers to the map. 
	* 
	* @method loadLayers
	* @param [{layerConfig}] layers Array of layerConfig objects 
	* 
	*/    
	
    loadLayers: function (layers) {
		
		if (CWN2.base.DEBUG) {
			console.log('CWN2.MapBuilder.loadLayers');
		}

		// aggiungo i layers alla mappa OL
		for (var i = 0; i < layers.length; i++) {
			this.loadLayer(layers[i]);
		}

	},	

	/**
	* 
	* Add a layer to the map. 
	* 
	* @method loadLayer
	* @param {layerConfig} layerConfig A layerConfig object 
	* 
	*/    

    loadLayer: function (layerConfig) {
	
    	if (CWN2.base.DEBUG) {
			console.log('CWN2.MapBuilder.loadLayer');
		}

    	// creo il layer OL e lo aggiungo alla mappa
		CWN2.base.map.addLayer(CWN2.layerFactory.createLayer(layerConfig));
	},	
	
	/**
	* 
	* Initialize and load the controls of the map. 
	* 
	* @method initControls
	* @param [{controlsConfig}] controls Array of controlsConfig objects 
	* 
	*/    
	
    initControls: function (controlConfig) {
		
		// Carico i controlli base
		baseControlConfig = [
			{   
				"type": "Navigation"
			},
			{   
				"type": "ArgParser"
			},
			{   
				"type": "Attribution"
			},
			{   
				"type": "KeyboardDefaults"
			}
		];
		this.loadControls(baseControlConfig);
		
		// registro il controllo per la selezione delle feature dei livelli vettoriali
		this.activateSelectFeatureControl();

		// Carico i controlli dalla configurazione
		this.loadControls(controlConfig);

	},	

	/**
	* 
	* Add an array of controls to the map. 
	* 
	* @method loadControls
	* @param [{controlConfig}] controls Array of controlConfig objects 
	* 
	*/    
	
    loadControls: function (controls) {
		
		if (CWN2.base.DEBUG) {
			console.log('CWN2.MapBuilder.loadControls');
		}

		// aggiungo i controlli alla mappa OL
		for (var i = 0; i < controls.length; i++) {
			this.loadControl(controls[i]);
		}

	},	

	/**
	* 
	* Add a control to the map. 
	* 
	* @method loadControl
	* @param {controlConfig} controlConfig A controlConfig object 
	* 
	*/    

    loadControl: function (controlConfig) {
	
    	if (CWN2.base.DEBUG) {
			console.log('CWN2.MapBuilder.loadControl');
		}

    	// creo il controllo OL e lo aggiungo alla mappa
		var olControl = CWN2.controlFactory.createControl(controlConfig);
		CWN2.base.map.addControl(olControl);
		return olControl;
		
	},	

	/**
	* 
	* Activate the select feature control for all the vector layers of the map. 
	* 
	* @method activateSelectFeatureControl
	* 
	*/ 
	
    activateSelectFeatureControl: function () {
		
		if (CWN2.base.DEBUG) {
			console.log('CWN2.MapBuilder.activateSelectFeatureControl');
		}

		var map = CWN2.base.map;
		
		// carico l'array con i layer vettoriali
		var vectLayerArray = [];
		for (var i = 0; i < map.layers.length; i++) {
			if (map.layers[i].CLASS_NAME==='OpenLayers.Layer.Vector') {
				map.layers[i].events.on({
				    'featureselected': CWN2.event.onFeatureSelect,
				    'featureunselected': CWN2.event.onFeatureUnselect
				});
				vectLayerArray.push(map.layers[i]);
			}
		}
		// attivo il controllo
		var select_feature_control = new OpenLayers.Control.SelectFeature(vectLayerArray);
		map.addControl(select_feature_control);
		select_feature_control.activate();
		
	}			
	
};	
	

//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Classe CWN2.MapPanelBuilder - Build the MapPanel
* 
* @namespace CWN2
* @class MapPanelBuilder
* 
*/

CWN2.MapPanelBuilder = {
	
	/**
	* 
	* Build the MapPanel
	* 
	* @method build
	* 
	* 
	*/ 
	
	build: function() {
		
		return new GeoExt.MapPanel(this.loadPanelOptions());

	},
	
		/**
	* 
	* Load the panel options from the configurazion
	* 
	* @method loadPanelOptions
	* 
	* 
	*/ 
	
	loadPanelOptions: function() {

		var panelOptions = {
			id: "cwn2-map-panel",
	        renderTo: "mappanel",
	        map: CWN2.base.map
	    };

	    if (CWN2.configuration.layout.mapHeight) {
		    panelOptions.height = CWN2.configuration.layout.mapHeight;
		}
	    if (CWN2.configuration.layout.mapWidth) {
		    panelOptions.width = CWN2.configuration.layout.mapWidth;
		}
	    if (CWN2.configuration.layout.title) {
		    panelOptions.title = CWN2.configuration.layout.title;
		}

		// statusbar
		var statusbar = CWN2.StatusbarBuilder.build();
		panelOptions.bbar = statusbar;
		
		// toolbar
		if (CWN2.configuration.toolbar) {
			var toolbar = CWN2.ToolbarBuilder.build();
		    panelOptions.tbar = toolbar;
		}
		
		return panelOptions;
		
	}
	
};	
	

//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Oggetto per la creazione della statusbar
* 
* @namespace CWN2
* @class StatusbarBuilder
* 
*/

CWN2.StatusbarBuilder = {

	/**
	* 
	* Build the statusbar
	* 
	* @method build
	* 
	* 
	*/ 
	
	build: function() {

		// costruisco la statusbar
		var statusbarItems = [];
		
		// se presente widget CoordinateReadOut aggiungo i campi per X e Y
		if (CWN2.configuration.getWidgetConfigByType("CoordinateReadOut")) {
			var items = [
				{
					id : 'coordinate-readout',
					text : "Coordinate:",
					width : 200,
					xtype: "tbtext"
				}
			];
			statusbarItems.push(items);
		}

		// ritorno la statusbar
		return new Ext.Toolbar({id:"statusbar" , items: statusbarItems});
			
	}
	
};//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Oggetto per la creazione della toolbar
* 
* @namespace CWN2
* @class ToolbarBuilder
* 
*/

CWN2.ToolbarBuilder = {

	/**
	* 
	* Array degli elementi (bottoni/menu) disponibili
	* 
	* @property itemDefs
    * @type [{toolbarItem}]
	*/

	itemDefs: [],
	
	/**
	* 
	* Build the toolbar
	* 
	* @method build
	* 
	* 
	* 
	*/ 
	
	build: function() {
		
		// costruisco la toolbar
		var toolbarItems = [], actionOptions, actionConfig, action, control;

		// ciclo su tutti gli elementi della toolbar
		for (var group in CWN2.configuration.toolbar.itemGroups) {
			for (var item in CWN2.configuration.toolbar.itemGroups[group].items) {
				if (typeof(CWN2.configuration.toolbar.itemGroups[group].items[item]) != 'function') {
					// creo la action e la aggiungo alla toolbar
					//console.log(CWN2.configuration.toolbar.itemGroups[group].items[item]);
					var createFunction = CWN2.ToolbarBuilder.itemDefs[CWN2.configuration.toolbar.itemGroups[group].items[item].name].create;
					var itemOptions = CWN2.ToolbarBuilder.itemDefs[CWN2.configuration.toolbar.itemGroups[group].items[item].name].options;
					var item = createFunction(itemOptions);
					//console.log(item);
					toolbarItems.push(item);
				}
			};
			if (group < CWN2.configuration.toolbar.itemGroups.length - 1) {
				toolbarItems.push("-");
			}
		};

		// aggiungo il bottone di help
		toolbarItems.push("->");
		var createFunction = CWN2.ToolbarBuilder.itemDefs["help"].create;
		var itemOptions = CWN2.ToolbarBuilder.itemDefs["help"].options;
		var item = createFunction(itemOptions);
		toolbarItems.push(item);
		
		return new Ext.Toolbar({id:'toolbar', items: toolbarItems});
			
	}
};//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Oggetto per la creazione dell'inerterfaccia grafica
* 
* @namespace CWN2
* @class UIBuilder
* 
*/

CWN2.UIBuilder = {

	/**
	* 
	* Build the interface
	* 
	* @method build
	* 
	* @param {String} div Name of the div   
	* 
	*/ 
	
	build: function(div) {
		
		// Costruisco la mappa
		CWN2.MapBuilder.build(div);

		// Configuro e costruisco il MapPanel
	    var mapPanel = CWN2.MapPanelBuilder.build();

		// carico i widgets
		this.loadWidgets();

		// costruisco la window per l'help
		this.buildHelpWindow();

	},
	
	/**
	* 
	* Load the widgets
	* 
	* @method loadWidgets
	* 
	* 
	*/ 
	
	loadWidgets: function() {

		var widgets = CWN2.configuration.widgets;
		var len = widgets.length;
		for (var i = 0; i < len; i++) {
	 		CWN2.widgetFactory.create(widgets[i])
		}
	},

	/**
	* 
	* Build the Help window
	* 
	* @method buildHelpWindow
	* 
	* 
	*/ 
	
	buildHelpWindow: function() {

		new Ext.Window({
	        title: "Help",
			id: "help-win",
	        height: 400,
	        width: 600,
	        layout: "fit",
	        closeAction: "hide",
	        items: []
	    });
		
	}
		
	
};//#include <base.js>
//#include <openlayersExt.js>
//#include <event.js>


/**
* 
* Factory per creazione di widget 
* 
* @namespace CWN2
* @class widgetFactory
* 
*/

CWN2.widgetFactory = {

	/**
	* 
	* Create an widget
	* 
	* @method create
	* 
	* @param {widgetConfig} widgetConfig Obj containing the widget configuration 
	* 
	* @return: 	{OpenLayers.Layer}
	* 
	*/ 
	
	create: function(widgetConfig) {

		if (CWN2.base.DEBUG) {
			console.log('CWN2.widgetFactory.create');
		}
		return CWN2.widgetFactory[widgetConfig.type](widgetConfig);
	
	},
	
	
	CoordinateReadOut: function(widgetConfig) {

		if (CWN2.base.DEBUG) {
			console.log('CWN2.widgetFactory.CoordinateReadOut');
		}
		
		var cbFunction = function(e) {
			
			var lonLat = this.getLonLatFromPixel(e.xy);
			
			// TODO: gestione conversione coordinate da 900913 a GB / WGS84
			/*		
				if (this.displayProjection) {
				lonLat.transform(this.getProjectionObject(),
						this.displayProjection);
			} 
			*/
		
			//Ext.getCmp("x-coord").setText("X: " + lonLat.lon.toFixed(0));
			//Ext.getCmp("y-coord").setText("Y: " + lonLat.lat.toFixed(0));
			Ext.getCmp("coordinate-readout").setText("Coordinate: X=" + lonLat.lon.toFixed(0) + " Y=" + lonLat.lat.toFixed(0));

		}
		
		// registro l'evento sul mousemove (scrittura coodinate su statusbar)
		CWN2.base.map.events.register("mousemove", CWN2.base.map, cbFunction);


		return null;
	
	}


};
var button = {
	options : {
		tooltip: "Fit All - Visualizza alla massima estensione",
		iconCls: "fit",
		pressed: false,
		control : new OpenLayers.Control.ZoomToMaxExtent(),
		id: "fitall"
	},
	create : function(options) {
		CWN2.base.map.addControl(options.control);
		return new GeoExt.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
			options : {
				tooltip: "Pan",
				iconCls: "pan",
				enableToggle: true,
				pressed: true,
				control: new OpenLayers.Control.Navigation(),
				id:"pan",
				toggleGroup: "toolGroup"
			},
			create : function(options) {
				CWN2.base.map.addControl(options.control);
				return new GeoExt.Action(options);
			}

}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
	options :
	{
		tooltip: "Vai alla Visualizzazione Successiva",
		iconCls: "zoomnext",
		disabled: true,
		//enableToggle: true,
		pressed: false,
		id: "zoomnext"
	},
	create : function(options) {
		// create a navigation history control
		var historyControl = null; 
		var controls = CWN2.base.map.getControlsByClass("OpenLayers.Control.NavigationHistory");
		if (controls.length === 0) {
			historyControl = new OpenLayers.Control.NavigationHistory();
			CWN2.base.map.addControl(historyControl);						
		} else {
			historyControl = controls[0];
		} 			
		options.control = historyControl.next;
		return new GeoExt.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
	options : {
		tooltip: "Vai alla Visualizzazione Precedente",
		iconCls: "zoomprevious",
		//enableToggle: true,
		disabled: true,
		pressed: false,
		id: "zoomprevious"
	},
	create : function(options) {
		// create a navigation history control
		var historyControl = null; 
		var controls = CWN2.base.map.getControlsByClass("OpenLayers.Control.NavigationHistory");
		if (controls.length === 0) {
			historyControl = new OpenLayers.Control.NavigationHistory();
			CWN2.base.map.addControl(historyControl);						
		} else {
			historyControl = controls[0];
		} 			
		options.control = historyControl.previous;
		return new GeoExt.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
	options: {
		tooltip: "Zoom Out",
		iconCls: "zoomout",
		enableToggle: true,
		pressed: false,
		control: new OpenLayers.Control.ZoomBox({
			out: true
		}),
		id: "zoomout",
		toggleGroup: "toolGroup"
	},
	create: function(options){
		CWN2.base.map.addControl(options.control);
		return new GeoExt.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
	options :
	{
		tooltip: "Misure Lineari",
		iconCls: "measureline",
		enableToggle: true,
		pressed: false,
		control : new OpenLayers.Control.Measure(OpenLayers.Handler.Path, {
			persist: true,
			eventListeners: {
				measure: function(evt){
					var out = '';
					out += 'Distanza: ' + evt.measure.toFixed(3) + " " + evt.units;
					Ext.getCmp("bbar_measure").setText(out);
				},
				measurepartial: function(evt){
					var out = '';
					out += 'Distanza: ' + evt.measure.toFixed(3) + " " + evt.units;
					Ext.getCmp("bbar_measure").setText(out);
				}
			}
		}),
		id: "measureline",
		toggleGroup: "toolGroup"

	},
	create : function(options) {
		CWN2.base.map.addControl(options.control);
		
		// aggiungo alla statusbar il campo per la visualizzazione delle misure
		if (!Ext.getCmp("bbar_measure")) {
			var item = {
				id: 'bbar_measure',
				text: "",
				width: 200,
				xtype: "tbtext"
			};
			Ext.getCmp("statusbar").add(item);
		}
		return new GeoExt.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;


var button = {
			options : {
				tooltip: "Zoom In",
				iconCls: "zoomin",
				enableToggle: true,
				pressed: false,
				control : new OpenLayers.Control.ZoomBox(),
				id: "zoomin",
				toggleGroup: "toolGroup"
			},
			create : function(options) {
				CWN2.base.map.addControl(options.control);
				return new GeoExt.Action(options);
			}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
	options : {
		id:"help",
		tooltip: "Help",
		iconCls: "help",
		pressed: false,
		handler: function(){
			// rendo visibile la finestra dell'help
	        Ext.getCmp("help-win").show();
	    }
	},
	create : function(options) {
		return new Ext.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

var button = {
	options :
	{
		tooltip: "Misure Areali",
		iconCls: "measurearea",
		enableToggle: true,
		pressed: false,
		control: new OpenLayers.Control.Measure(OpenLayers.Handler.Polygon, {
			persist: true,
			eventListeners: {
				measure: function(evt){
					var out = '';
					out += 'Area: ' + evt.measure.toFixed(3) + " " + evt.units + "2";
					Ext.getCmp("bbar_measure").setText(out);
				},
				measurepartial: function(evt){
					var out = '';
					out += 'Area: ' + evt.measure.toFixed(3) + " " + evt.units + "2";
					Ext.getCmp("bbar_measure").setText(out);
				}
			}
		}),
		id: "measurearea",
		toggleGroup: "toolGroup"

	},
	create : function(options) {
		CWN2.base.map.addControl(options.control);
		
		// aggiungo alla statusbar il campo per la visualizzazione delle misure
		if (!Ext.getCmp("bbar_measure")) {
			var item = {
				id: 'bbar_measure',
				text: "",
				width: 200,
				xtype: "tbtext"
			};
			Ext.getCmp("statusbar").add(item);
		}
		
		return new GeoExt.Action(options);
	}
}

CWN2.ToolbarBuilder.itemDefs[button.options.id] = button;

